package org.datascooter.test;

import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.datascooter.DataScooter;
import org.datascooter.exception.EntityNotMappedException;
import org.datascooter.extension.DatascooterStarter;
import org.datascooter.test.jpaSimple.Address;
import org.datascooter.test.jpaSimple.Customer;
import org.datascooter.test.jpaSimple.DeliveryService;
import org.datascooter.test.jpaSimple.Order2;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * Simple example from JSR 220
 * 
 * @author nemo
 * 
 */
public class JPATestSimple {

	private static Address address1, address2, address3, address4;
	private static Customer customer1, customer2, customer3, customer4;
	private static DeliveryService service1, service2, service3, service4;
	private static Order2 order1, order2, order3, order4;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		DatascooterStarter.startEclipseDefaultPath();
		DataScooter.getDefault().dropAll("", true);
		DataScooter.getDefault().verifyTables();
	}
	private ArrayList<Order2> orderList;
	private Set<DeliveryService> serviceSet;

	@Test
	public void testAll() throws EntityNotMappedException, SQLException, IOException {
		createAddresses();
		createCustomers();
		createDeliveryService();
		createOrder();
		list();
		testUpdate();
		testDelete();
		testReferences();
	}

	public void createAddresses() throws EntityNotMappedException {
		address1 = new Address();
		address2 = new Address();
		address3 = new Address();
		address4 = new Address();
		DataScooter.getDefault().save(address1);
		DataScooter.getDefault().save(address2);
		DataScooter.getDefault().save(address3);
		DataScooter.getDefault().save(address4);
	}

	public void createCustomers() throws EntityNotMappedException {
		customer1 = new Customer();
		customer2 = new Customer();
		customer3 = new Customer();
		customer4 = new Customer();
		customer1.setDescription("customer1");
		customer2.setDescription("customer2");
		customer3.setDescription("customer3");
		customer4.setDescription("customer4");
		DataScooter.getDefault().save(customer3);
		DataScooter.getDefault().save(customer4);
	}

	public void createDeliveryService() {
		service1 = new DeliveryService();
		service2 = new DeliveryService();
		service3 = new DeliveryService();
		service4 = new DeliveryService();
		serviceSet = new HashSet<DeliveryService>();
		serviceSet.add(service1);
		serviceSet.add(service3);
		customer2.setDescription("customer2222222");
		customer2.setServiceOptions(serviceSet);
		DataScooter.getDefault().save(customer2);
		// DataScooter.getDefault().saveOrUpdate(service1);
		DataScooter.getDefault().saveOrUpdate(service2);
		// DataScooter.getDefault().saveOrUpdate(service3);
		DataScooter.getDefault().saveOrUpdate(service4);
	}

	public void createOrder() {
		order1 = new Order2();
		order2 = new Order2();
		order3 = new Order2();
		order4 = new Order2();
		orderList = new ArrayList<Order2>();
		// order1.setCustomer(customer2);
		orderList.add(order1);
		// order2.setCustomer(customer4);
		orderList.add(order2);
		customer1.setOrders(orderList);
		DataScooter.getDefault().save(customer1);
		// DataScooter.getDefault().saveOrUpdate(order1);
		// DataScooter.getDefault().saveOrUpdate(order2);
		DataScooter.getDefault().save(order3);
		DataScooter.getDefault().save(order4);
	}

	public void list() throws EntityNotMappedException, SQLException, IOException {
		int size = DataScooter.getDefault().list(Address.class).size();
		assertTrue("Count of Address:  " + size, size == 4);
		assertTrue((DataScooter.getDefault().list(Customer.class).size() == 4));
		assertTrue((DataScooter.getDefault().list(DeliveryService.class).size() == 4));
	}

	public void testUpdate() throws EntityNotMappedException, SQLException, IOException {
		DataScooter.getDefault().update(address1, "street", "Baker St");
		DataScooter.getDefault().update(address2, "street", "Abby road");
		assertTrue(((Address) DataScooter.getDefault().firstById(Address.class, address1.getId())).getStreet().equals("Baker St"));
		assertTrue(((Address) DataScooter.getDefault().firstById(Address.class, address2.getId())).getStreet().equals("Abby road"));
	}

	public void testDelete() throws EntityNotMappedException, SQLException, IOException {
		DataScooter.getDefault().delete(address1);
		DataScooter.getDefault().delete(Address.class, "street", "Abby road");
		assertTrue(DataScooter.getDefault().firstById(Address.class, address1.getId()) == null);
		assertTrue(DataScooter.getDefault().first(Address.class, "street", "Abby road") == null);
	}

	public void testReferences() {
		customer1 = DataScooter.getDefault().firstById(Customer.class, customer1.getId());
		List<Order2> list = customer1.getOrders();
		assertTrue("List size: " + list.size(), list.size() == 2);
		customer2 = DataScooter.getDefault().firstById(Customer.class, customer2.getId());
		Set<DeliveryService> set = customer2.getServiceOptions();
		assertTrue("Set size: " + set.size(), set.size() == 2);
	}

	@AfterClass
	public static void tearDown() throws Exception {
		DataScooter.getDefault().dropAll("", true);
		DataScooter.getDefault().close();
	}
}
